<?php

namespace app\lib\pay;
use app\common\model\MbtiOrder;
use EasyWeChat\Factory;
use EasyWeChat\Kernel\Exceptions\Exception;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use EasyWeChat\Kernel\Support\Collection;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;
use think\facade\Db;
use think\facade\Log;

class wxPay
{

    protected $app;

    public function __construct()
    {
        $config = [
            'app_id' => env('wx.app_id'),
            'mch_id' => env('wx.mch_id'),
            'key' => env('wx.key'),
            'notify_url' => env('wx.callback_addr'),     // 你也可以在下单时单独设置来想覆盖它
            // Guzzle 客户端配置
            'http' => [
                'verify' => false, // 关闭 SSL 验证
            ],
        ];
        $this->app = Factory::payment($config);
    }

    /**
     * 微信统一下单
     * @param $data
     * @param string $tradeType
     * @param string $openId
     * @return array|Collection|object|ResponseInterface|string
     * @throws InvalidArgumentException
     * @throws InvalidConfigException
     * @throws GuzzleException
     */
    public function createOrder($data,$tradeType = 'NATIVE',$openId = '')
    {
        if (!empty($tradeType)) {
            $data['trade_type'] = $tradeType;
        }
        if (!empty($openId)) {
            $data['openid'] = $openId;
        }
        $data['notify_url'] = env('wx.callback_addr');
        //记录订单
        Db::startTrans();
        try {
            $orderNo = (new MbtiOrder())->addData(
                $data['business_order_no'],
                $data['total_fee'],
                'wx'
            );
            Db::commit();
        } catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw new Exception("下单失败");
        }
        $amount = $data['total_fee'];
        unset($data['business_order_no']);
        $data['total_fee']  =$data['total_fee'] * 100;
        $data['out_trade_no'] = $orderNo;
        $res = $this->app->order->unify($data);
        if ($res['return_code'] != 'SUCCESS') {
            throw new \Exception("下单失败");
        }
        $res['amount'] = $amount;
        $res['order_no'] = $orderNo;
        $res['qrcode'] = qrcode($res['code_url']);
        return $res;
    }

    //根据商户订单号查询
    public function queryByOutTradeNumber($out_trade_no)
    {
        return $this->app->order->queryByOutTradeNumber($out_trade_no);
    }

    //根据微信订单号查询
    public function queryByTransactionId($transactionId)
    {
        return $this->app->order->queryByTransactionId($transactionId);
    }

    /**
     * 处理微信通知
     * @return \Symfony\Component\HttpFoundation\Response
     * @throws Exception
     */
    public function handleRefundedNotify()
    {
        $response = $this->app->handlePaidNotify(function ($message, $fail) {
            Log::info('handleRefundedNotify'.json_encode($message));
            $orderNo = $message['out_trade_no'];
            $order = MbtiOrder::where('order_no', $orderNo)->find();
            if (empty($order) || $order['is_pay'] != 1) { // 如果订单不存在 或者 订单已经支付过了
                return true; // 告诉微信，我已经处理完了，订单没找到，别再通知我了
            }
            if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态，不代表支付状态
                //更新支付状态
                MbtiOrder::where(['order_no' => $orderNo])
                    ->update(['is_pay' => 1, 'pay_date' => date('Y-m-d H:i:s'),'trade_no' => $message['out_trade_no'],'transaction_id' => $message['transaction_id']]);
            }else{
                MbtiOrder::where(['order_no' => $orderNo])->update(['remark' =>  json_encode($message)]);
            }
            return true; // 返回处理完成
        });
        $response->send(); // return $response;
    }

}